package com.taokatao.cardmee.business.profile;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.Paint;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.gson.reflect.TypeToken;
import com.taokatao.cardmee.App;
import com.taokatao.cardmee.BusEvent;
import com.taokatao.cardmee.C;
import com.taokatao.cardmee.R;
import com.taokatao.cardmee.Utils;
import com.taokatao.cardmee.api.ApiManager;
import com.taokatao.cardmee.api.RespWrapper;
import com.taokatao.cardmee.api.SubscriberAdapter;
import com.taokatao.cardmee.db.MessageDao;
import com.taokatao.cardmee.db.model.Message;
import com.taokatao.cardmee.util.PtrHeaderHelper;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import de.greenrobot.event.EventBus;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;


public class ProfileMessageLayout extends LinearLayout {
    @BindView(R.id.l_empty) View lEmpty;
    @BindView(R.id.l_top_count) View lTopCount;
    @BindView(R.id.t_top_count) TextView tTopCount;
    @BindView(R.id.v_recycler) RecyclerView vRecycler;
    @BindView(R.id.l_ptr_frame) PtrFrameLayout lPtrFrame;
    private MessageAdapter adapter;
    private int mMessageType;
    private Callback cb;

    public void setCallback(Callback callback) {
        cb = callback;
    }

    public ProfileMessageLayout(Context context) {
        this(context, null);
    }

    public ProfileMessageLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        ButterKnife.bind(this, LayoutInflater.from(context).inflate(R.layout.layout_profile_message, this));

        vRecycler.setLayoutManager(new LinearLayoutManager(context));
        vRecycler.setAdapter(adapter = new MessageAdapter());

        PtrHeaderHelper.initDefault(getContext(), lPtrFrame);
        lPtrFrame.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return PtrDefaultHandler.checkContentCanBePulledDown(frame, vRecycler, header);
            }

            @Override
            public void onRefreshBegin(final PtrFrameLayout frame) {
                // wait for SwipeItem close, avoid ui cache in list bug
                lPtrFrame.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (Message.MESSAGE_TYPE_BUSINESS == mMessageType) {
                            requestGetMyMessageList();
                        } else if (Message.MESSAGE_TYPE_SYS == mMessageType) {
                            lPtrFrame.refreshComplete();
                        } else {
                            lPtrFrame.refreshComplete();
                        }
                    }
                }, C.settings.ANIMATION_TIME);
            }
        });
    }

    private void requestGetMyMessageList() {
        long syncStartTime = Utils.spReadLong("api_getMyMessageList", 20161121000000l);
        ApiManager.i().getMyMessageList(getContext(), App.i().getCurrUser().getUuid(), syncStartTime, new SubscriberAdapter<RespWrapper<List<Message>>>() {
            @Override
            public void onNext(RespWrapper<List<Message>> o) {
                super.onNext(o);
                if (o.code == C.http.RESULT_CODE_SUCCESS) {
                    List<Message> remoteMessageList = o.decode(new TypeToken<List<Message>>() {
                    }.getType());

                    if (remoteMessageList != null) {
                        for (Message m : remoteMessageList) {
                            m.setHadRead(Message.READ_READ);
                            m.setMMessageType(Message.MESSAGE_TYPE_BUSINESS);
                        }
                    }

                    prepareDataByDBQuery(remoteMessageList);
                }
            }
        }.pullToRefresh(lPtrFrame));
    }

    ViewPropertyAnimator animator;

    public void removeTips() {
        if (lTopCount.getVisibility() == View.VISIBLE) {
            if (animator != null) return;
            animator = lTopCount.animate();
            animator.alpha(0).setStartDelay(2000).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    lTopCount.setVisibility(View.GONE);
                    lTopCount.setAlpha(1f);
                    animator = null;
                }
            });
            animator.start();
        }
    }

    private void prepareDataByDBQuery(List<Message> remoteMessageList) {
        Utils.logd("card layout prepareDataByDBQuery ~ remoteCardList " + (remoteMessageList != null ? "[" + remoteMessageList.size() + "]" : "null"));
        if (App.i().getCurrUser() != null) {
            MessageDao messageDao = App.i().getUserDBSession().getMessageDao();
            List<Message> localMessageList = messageDao.queryBuilder().orderDesc(MessageDao.Properties.CreateTime).where(
                    MessageDao.Properties.MMessageType.eq(mMessageType)
            ).list();

            int unreadCount = 0;
            for (Message m : localMessageList) {
                if (m.getHadRead() == null || m.getHadRead() != Message.READ_READ) {
                    unreadCount++;

                    m.setHadRead(Message.READ_READ);
                    messageDao.insertOrReplace(m);
                }
            }
            lTopCount.setVisibility(unreadCount != 0 ? View.VISIBLE : View.GONE);
            tTopCount.setText("已为您展示" + unreadCount + "条最新内容");
            // 只有仅在加载本地数据的时候
            if (cb != null && remoteMessageList == null) cb.onDataRefresh(mMessageType, unreadCount);

            if (remoteMessageList != null) {
                Iterator<Message> messageIterator = localMessageList.iterator();
                while (messageIterator.hasNext()) {
                    Message c = messageIterator.next();
                    int mirrorIdx = remoteMessageList.indexOf(c);
                    if (mirrorIdx == -1) {
                        //Utils.logd("card refresh remove [%s]", c.toString());
                    } else {
                        Message mirror = remoteMessageList.get(mirrorIdx);
                        // Utils.loge("card refresh update mirror [%s]", mirror.toString());
                        c.refreshProperties(mirror);
                        // Utils.logd("card refresh update [%s]", c.toString());
                        messageDao.insertOrReplace(c);
                        remoteMessageList.remove(mirror);
                    }
                }

                localMessageList.addAll(remoteMessageList);
                messageDao.insertOrReplaceInTx(remoteMessageList);
            }

            Collections.sort(localMessageList, cardSortByCreateTime);
            adapter.set(localMessageList);

            lEmpty.setVisibility(localMessageList.size() < 1 ? View.VISIBLE : View.GONE);
        }
    }


    private final Comparator<Message> cardSortByCreateTime = new Comparator<Message>() {
        @Override
        public int compare(Message lhs, Message rhs) {
            if (lhs.getCreateTime() == null) return 1;
            else if (rhs.getCreateTime() == null) return -1;

            return lhs.getCreateTime() > rhs.getCreateTime() ? -1 : 1;
        }
    };

    public void setMessageType(int messageType) {
        mMessageType = messageType;

        adapter.setType(mMessageType);
        prepareDataByDBQuery(null);
    }

    private static class MessageAdapter extends RecyclerView.Adapter {
        private final List<Message> dataList = new ArrayList<>();
        private final SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmmss");
        private final SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        private int mMessageType;

        public void setType(int messageType) {
            mMessageType = messageType;
        }

        public void set(List<Message> sourceList) {
            if (sourceList == null) return;
            dataList.clear();
            dataList.addAll(sourceList);
            notifyDataSetChanged();
        }

        class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
            TextView tBusinessName, tTime, tContent, tTitle , tMore;
            View vLast;
            Message m;

            ViewHolder(View itemView) {
                super(itemView);
                vLast = itemView.findViewById(R.id.v_last);
                tBusinessName = (TextView) itemView.findViewById(R.id.t_business_name);
                tTime = (TextView) itemView.findViewById(R.id.t_time);
                tContent = (TextView) itemView.findViewById(R.id.t_content);
                tTitle = (TextView) itemView.findViewById(R.id.t_title);
                tMore = (TextView) itemView.findViewById(R.id.t_more);
                tMore.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG);
                tMore.setOnClickListener(this);

                tBusinessName.setVisibility(mMessageType == Message.MESSAGE_TYPE_SYS ? View.GONE : View.VISIBLE);
            }

            @Override
            public void onClick(View v) {
                if(v == tMore) {
                    tMore.setVisibility(View.GONE);
                    tContent.setText(m.getMessage());
                }
            }

            void refresh(Message message) {
                m = message;
                if (m != null) {
                    itemView.setVisibility(View.VISIBLE);
                    tBusinessName.setText(m.getSname());
                    String sContent = m.getMessage();
                    if (!TextUtils.isEmpty(sContent) && sContent.length() > 64) {
                        sContent = sContent.substring(0, 64) + "...";
                        tMore.setVisibility(View.VISIBLE);
                    }
                    tContent.setText(sContent);
                    tTitle.setText(m.getMessageTitle());
                    try {
                        Date date = sdf1.parse(String.valueOf(m.getCreateTime()));
                        tTime.setText(sdf2.format(date));
                    } catch (Exception e) {
                        e.printStackTrace();
                        tTime.setText("");
                    }
                } else {
                    itemView.setVisibility(View.GONE);
                }
            }
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_profile_message, parent, false));
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ViewHolder vh = (ViewHolder) holder;
            vh.vLast.setVisibility(position >= dataList.size() - 1 ? View.VISIBLE : View.GONE);
            vh.refresh(dataList.get(position));
        }

        @Override
        public int getItemCount() {
            return dataList.size();
        }
    }


    public void onEventMainThread(BusEvent event) {
        if (event.type == BusEvent.TYPE_MAIN_THREAD) {
            switch (event.action) {
                case BusEvent.MESSAGE_SYS_BY_PUSH:
                    if (mMessageType == Message.MESSAGE_TYPE_SYS) {
                        // 极光推送系统消息，刷新本地界面
                        prepareDataByDBQuery(null);
                    }
                    break;
            }
        }
    }


    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        EventBus.getDefault().unregister(this);
    }

    public interface Callback {
        void onDataRefresh(int messageType, int unReadCount);
    }
}
